﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace ReplaceCsv.WallLogParser
{
    //#ジエスタ対応#
    class GiestaParser
    {
        //ジエスタのログ解析用のクラス。
        //１．正規表現
        //２．マッチしたときの位置と格納情報位置
        //３．削除するリスト
        //４．日本語に置換するリスト
        //それぞれの処理をパラメータベースで作成する
        private string category;
        private Regex matchPattern;
        private Dictionary<int, int> matchGroups;
        private List<string> delList;
        private Dictionary<string, string> convertRegList;

        internal GiestaParser(string category,string regString, Dictionary<int, int> matchInfo, List<string> delList, Dictionary<string, string> convert)
        {
            try
            {
                matchPattern = new Regex(regString);
            }
            catch (Exception ex)
            {
                //正規表現のインスタンス生成時のエラー
                //あとで必ずロジック化
                throw ex;
            }
            //本当はdeepcopyがよいが、いったんは上位側のインスタンスをそのまま引き継ぐ形とする
            this.category = category;
            this.matchGroups = matchInfo;
            this.delList = delList;
            this.convertRegList = convert;
        }
        public bool isCategory(string logLine, out GiestaInfoBean bean)
        {
            bool result = false;
            Match mt = null;
            bean = null;

            mt = matchPattern.Match(logLine);
            if( mt.Success ) {
                List<string> info = getMatches(mt);

                bean = new GiestaInfoBean(this.category, info);                 
                result = true;
            }
            return result;
        }
        private List<string> getMatches(Match mt)
        {
            List<string> result = new List<string>();
            GroupCollection mg = mt.Groups;
            int mgCount =  mg.Count;
            string dbg = mt.Groups[0].Value;
            foreach (KeyValuePair<int, int> k in this.matchGroups)
            {
                //count とキャプチャの関係はあとで再チェック！！！
                if ((k.Key <= mgCount))
                {
                    setInitialList(result, k.Value);
                    result[k.Value] = getTreatString(mg[k.Key].Value);
                }
            }
            return result;
        }
        private string getTreatString(string capString)
        {
            string result = capString;
            if (this.delList != null)
            {
                foreach (string d in this.delList)
                {
                    result = Regex.Replace(result, d, "");
                }
            }
            return getConvertString(result);
        }
        private string getConvertString(string delString)
        {
            string result = delString;
            foreach (KeyValuePair<string, string> k in this.convertRegList)
            {
                result = Regex.Replace(result, k.Key, k.Value);
            }
            return result;
        }
        private void setInitialList(List<string> target, int count)
        {
            if (target.Count <= count)
            {
                int max = count + 1 - target.Count;
                for (int i = 0; i < max; i++)
                {
                    target.Add(null);
                }
            }
        }
    }
}
